package com.bracketbird.client.gui.club.tournament.rtc;


import com.bracketbird.client.gui.club.tournament.*;
import com.bracketbird.client.model.*;
import com.bracketbird.client.model.keys.*;
import com.bracketbird.client.model.tournament.*;
import com.bracketbird.clientcore.gui.*;
import com.bracketbird.clientcore.style.*;

import java.util.*;

/**
 *
 */
public class LevelResultPanel extends VerticalComponent {


    private TournamentLevel level;
    private SimplePanelComponent levelEmptyPanelHolder = new SimplePanelComponent();
    private SimplePanelComponent matchesHolder = new SimplePanelComponent();
    private SimplePanelComponent finalRankingHolder = new SimplePanelComponent();
    private int levelCount;

    private TournamentListener<LevelStateEvent> stateListener = new TournamentListener<LevelStateEvent>() {
        public void onChange(LevelStateEvent event) {
            if (event.getNewState() instanceof LevelStateMatchesLayedOut) {
                showMatchesLayedoutPanel();
            }
            else if (event.getNewState() instanceof LevelStateEmpty) {
                showLevelEmptyPanel();
            }
            else if (event.getNewState() instanceof LevelStateAllMatchesPlayed) {
                showAllMatchesPlayedRanking();
            }
            else if (event.getNewState() instanceof LevelStateInFinished) {
                showFinalRanking(level.getEndingTeams());
            }
            else if (event.getNewState() instanceof LevelStateInProgress) {
                showLevelInProgress();
            }
        }


    };


    private void reset() {
        levelEmptyPanelHolder.clear();
        matchesHolder.clear();
        finalRankingHolder.clear();
    }

    public LevelResultPanel(TournamentLevel l, int levelCount) {
        super();
        this.levelCount = levelCount;
        this.level = l;
        init();
    }

    private void init() {
        level.addStateListener(stateListener);
        add(getHeaderLabel(), RTCLayoutFac2.h1());
        add(levelEmptyPanelHolder);
        add(matchesHolder, new TextLayout(10, 0, 30, 0, null, "100%"));
        add(finalRankingHolder, new TextLayout(0, 0, 30, 0, null, "100%"));
        initialSetup();
    }

    public void showAllMatchesPlayedRanking() {
        if (level.isCup()) {
            //find ranking and set ending teams
            List<PlayingTeamId> teams = new ArrayList<PlayingTeamId>();
            Map<PlayingTeam, PlayingTeam> usedTeamsMap = new HashMap<PlayingTeam, PlayingTeam>();

            for (int i = level.getRounds().size() - 1; i >= 0; i--) {
                Round r = level.getRounds().get(i);
                for (Match match : r.getMatches()) {
                    PlayingTeam winTeam = match.getWinningTeam();
                    if (!usedTeamsMap.containsKey(winTeam)) {
                        usedTeamsMap.put(winTeam, winTeam);
                        teams.add(winTeam.getId());
                    }
                }
            }

            //the losers from the first round should also be added
            for (Round round : level.getRounds()) {
                for (Match match : round.getMatches()) {
                    PlayingTeam loseTeam = match.getLosingTeam();
                    if (loseTeam.isWalkover() || usedTeamsMap.containsKey(loseTeam)) {
                        //ignore
                    }
                    else {
                        teams.add(loseTeam.getId());
                    }
                }
            }
            RTC.getInstance().getTournament().finishedLevel(level, new LevelFinishedVO(teams), true);
        }
        else {
            FinalGroupRankingPanel fr = new FinalGroupRankingPanel((Group) level);
            finalRankingHolder.add(fr, new TextLayout(null, "100%").backgroundGreyLight().paddingBottom(30));
            fr.build();
        }

    }

    public void showFinalRanking(List<PlayingTeam> finalRankOfTeams) {
        if (level.isCup()) {
            buildFinalRankingCup(finalRankOfTeams);
        }
        else {
            buildFinalRankingGroup(finalRankOfTeams);
        }

    }


    private void buildFinalRankingGroup(List<PlayingTeam> finalRankOfTeams) {
        VerticalComponent vc = new VerticalComponent();
        vc.add(new LabelComponent("Final ranking"), FinalRankListPanel.titleLayout);

        int positionCount = 1;
        TextLayout rLayout = new TextLayout(null, "350px").padding(2, 5, 2, 10);

        for (PlayingTeam team : finalRankOfTeams) {
            vc.add(new FinalRankRow(team, positionCount++), rLayout);
        }
        finalRankingHolder.add(vc, new TextLayout(null, "100%").backgroundGreyLight().paddingBottom(30));

    }


    private void buildFinalRankingCup(List<PlayingTeam> finalRankOfTeams) {
        VerticalComponent vc = new VerticalComponent();
        vc.add(new LabelComponent("Final ranking"), FinalRankListPanel.titleLayout);

        TextLayout rLayout = new TextLayout(null, "350px").padding(2, 5, 2, 10);

        vc.add(new FinalRankRow(finalRankOfTeams.get(0), 1), rLayout);
        vc.add(new FinalRankRow(finalRankOfTeams.get(1), 2), rLayout);

        int rowsToCreate = 2;
        int index = 0;
        while (index < rowsToCreate && (finalRankOfTeams.size() > (rowsToCreate + index))) {
            String position = rowsToCreate + 1 + "-" + rowsToCreate * 2;
            vc.add(new FinalRankRow(finalRankOfTeams.get(rowsToCreate + index), position), rLayout);
            index++;
            if (index == rowsToCreate) {
                rowsToCreate = rowsToCreate * 2;
                index = 0;
            }
        }

        finalRankingHolder.add(vc, new TextLayout(null, "100%").backgroundGreyLight().paddingBottom(30));
    }


    private LabelComponent getHeaderLabel() {
        return new LabelComponent(levelCount + ". stage (" + level.getName() + ")");
    }

    private void initialSetup() {
        if (level.isEmpty()) {
            showLevelEmptyPanel();
        }
        else {
            showMatchesLayedoutPanel();
        }
    }


    public void showMatchesLayedoutPanel() {
        reset();
        UpdatingTournamentInfoPanel.getInstance().setText("Laying out matches " + levelCount + ". stage (" + level.getName() + ")");
        PopupManager.show(UpdatingTournamentInfoPanel.getInstance(), null);
        matchesHolder.add(new LevelMatchesLayedOutPanel(level), new TextLayout(null, "100%"));
        PopupManager.hide();
    }

    public void showLevelEmptyPanel() {
        reset();
        levelEmptyPanelHolder.add(new LevelEmptyPanel(level));
    }

    private void showLevelInProgress() {
        finalRankingHolder.clear();
    }


}
